home *** CD-ROM | disk | FTP | other *** search
- TITLE LIGHTING - MATH FOR LIGHTING IN ASSEMBLER
-
- COMMENT $
-
-
- /* Routines for cosine or other lighting */
- /* All code and algorithms created by Dave Stampe */
- /* converted to assembly 17/12/93 by Dave Stampe */
-
- // All algorithms and code (c) 1993 by Dave Stampe
-
- /*
- This code is part of the REND386 project, created by Dave Stampe and
- Bernie Roehl.
-
- Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
-
- May be freely used to write software for release into the public domain;
- all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
- for permission to incorporate any part of this software into their
- products! Usually there is no charge for under 50-100 items for
- low-cost or shareware, and terms are reasonable. Any royalties are used
- for development, so equipment is often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to REND386, Dave Stampe,
- and Bernie Roehl in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling! No more
- code ripoffs please.
-
- CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
- See the COPYRITE.H file for more information.
- */
-
-
- This code does a very fast computation of cosine for lighting.
- It figures N.V/(mag(N)/mag(V) to 8 bit accuracy, where N is the poly
- normal, and V is the vector from the lightsource to the polygon.
- It is optimized by using the fact that the normls are all scaled to
- a known magnitude, and by preshifting V and N so an 8-bit multiply can be
- used in the magnitude computation.
-
- A value between -127 and +127 is returned for the cosine (-1.0 to +1.0)
-
- /* Contact: dstampe@sunee.waterloo.edu */
-
- $
-
- .MODEL large
-
- .DATA
-
- ; int sqrtable[1024];
- ; /*integer lookup for square root to 8 bit precision */
-
- extrn _sqrtable
-
-
- .CODE RENDERING
- .386
-
-
- MULT29 MACRO a,b ; multiply <3.29> -> eax
- mov eax,DWORD PTR a
- imul DWORD PTR b
- shrd eax,edx,29
- adc eax,0
- ENDM
-
- MMULT29 MACRO a,b,c ; multiply 3 of <3.29> -> eax
- mov eax,DWORD PTR a
- imul DWORD PTR b
- shrd eax,edx,29
- adc eax,0
- imul DWORD PTR c
- shrd eax,edx,29
- adc eax,0
- ENDM
-
- DOTPROD MACRO a,b,c,x,y,z,p ; dot product plus p, accum in ecx:ebx
- mov eax,a ; result in eax
- imul DWORD PTR x
- mov ecx,edx
- mov ebx,eax
- mov eax,b
- imul DWORD PTR y
- add ebx,eax
- adc ecx,edx
- mov eax,c
- imul DWORD PTR z
- add eax,ebx
- adc edx,ecx
- shrd eax,edx,29
- adc eax,p
- ENDM
-
- ;/************** FAST COSINE LIGHT ANGLE COMPUTE **********/
-
- ; /* compute vector from light source to surface */
- ; /* find dot product, normalize by vector length */
- ; /* returns -128<light<128 (signed 8-bit) */
- ; /* args: ligh characteristics, poly normal, point on poly */
- ; /* point on poly is 0,0,0 for spotlight */
- ;
- ;int light_cosine(long nx, long ny, long nz,
- ; long vx, long vy, long vz,
- ; long lx, long ly, long lz );
-
- nx equ [bp+8] ; arguments
- ny equ [bp+12]
- nz equ [bp+16]
- vx equ [bp+20]
- vy equ [bp+24]
- vz equ [bp+28]
- lx equ [bp+32]
- ly equ [bp+36]
- lz equ [bp+40]
-
- light equ [bp-4] ; locals
-
- PUBLIC _light_cosine
-
- _light_cosine proc far
-
- push ebp
- mov ebp,esp
- sub esp,4
-
- push esi ; normal is normalized, just need to
- push edi ; find size of light vector
- push ecx
- push edx
-
- mov eax,DWORD PTR lx ; delta X
- sub eax,vx
- mov ecx,eax
- jge xnn ; abs values -> ecx for scaling
- neg ecx
- xnn:
- mov vx,ecx
- mov ebx,ecx
- imul DWORD PTR nx ; nx*dx
- mov edi,edx
- mov esi,eax
-
- mov eax,DWORD PTR ly ; delta Y
- sub eax,vy
- mov ecx,eax
- jge ynn ; abs value
- neg ecx
- ynn:
- mov vy,ecx
- or ebx,ecx ; OR abs deltas for scaling test
- imul DWORD PTR ny
- add esi,eax ; and continue with dot product
- adc edi,edx
-
- mov eax,DWORD PTR lz ; same for Z
- sub eax,vz
- mov ecx,eax
- jge znn
- neg ecx
- znn:
- mov vz,ecx
- or ebx,ecx
- jnz golight ; /* max light at zero distance */
- mov ax,127
- jmp fincos
-
- golight:
- imul DWORD PTR nz
- add esi,eax
- adc edi,edx ;/* edi:esi now 64-bit dot product */
-
-
- ; START OF LIGHT VECTOR MAG COMPUTE
-
- shrd esi,edi,16 ; prescale
- sar edi,16 ; only did the prescale cause bsr
- ; is so slow on 386
- xor cx,cx
- test ebx,0ff000000h ; fast size tests, shifts
- je not32sig ; will let us use fast mults later
- add cx,16
- jmp shft16sig
- not32sig:
- test ebx,0ffff0000h
- je nonesig ; prescale by 8 bits */
- add cx,8
- shft16sig:
- shr ebx,cl ; conv. test to word (save 2 us) */
- nonesig:
-
- bsr ax,bx ; we test rest of bits
- add cx,ax
- sub cx,7 ; how many bits to normalize? */
- je noshiftn
- jl bumpup
-
- shr DWORD PTR vx,cl ; make into 8-bit numbers
- shr DWORD PTR vy,cl
- shr DWORD PTR vz,cl
- shrd esi,edi,cl
- sar edi,cl
- jmp noshiftn
- bumpup:
- neg cl
- shl DWORD PTR vx,cl
- shl DWORD PTR vy,cl
- shl DWORD PTR vz,cl
- shld edi,esi,cl
- shl esi,cl
-
- noshiftn:
- mov al,BYTE PTR vx ; now 8-bit diff's: find mag */
- mul al
- mov bx,ax ; square all components, sum
- xor dx,dx
-
- mov al,BYTE PTR vy
- mul al
- add bx,ax
- adc dx,0
-
- mov al,BYTE PTR vz
- mul al
- add bx,ax
- adc dx,0
-
- shrd bx,dx,7 ; lookup in sqrt table */
- and ebx,0FFFEh
- push esi
- les si,DWORD PTR _sqrtable
- mov ax,WORD PTR es:[bx+si]
-
- cwde
- pop esi
-
- ; END OF LIGHT VECTOR MAG COMPUTE
-
- mov ebx,eax
- mov edx,edi
- mov eax,esi
- idiv ebx ; remove magnitude from dot product
-
- fincos: ; result is now in ax: 127*cosine !
-
- pop edx
- pop ecx
- pop edi
- pop esi
-
- mov esp,ebp
- pop ebp
- ret
-
- _light_cosine endp
-
-
-
-
- end
-
-
-